home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / www / src / midaswww-1.0 / midas.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-16  |  66.1 KB  |  2,509 lines

  1. #include <stdio.h>                              /* For printf and so on. */
  2. #include <setjmp.h>                             /* For setjmp and so on. */
  3. #include <stdlib.h>                             /* for system() etc.     */
  4. #include <Mrm/MrmAppl.h>                        /* Motif Toolkit and MRM */
  5. #include <X11/CoreP.h>  
  6. #include <X11/cursorfont.h>
  7. #include <Xm/List.h>
  8. #include <Xm/PushB.h>
  9. #include <Xm/DialogS.h>    
  10. #include <Xm/Command.h>    
  11. #include <Xm/BulletinB.h>
  12. #include "SGMLHyper.h"     
  13. #include "SGMLCompositeText.h"     
  14. #include "midaslist.h"     
  15. #include "midasoperand.h"
  16. #include "midaswidget.h"
  17. #include "midasshell.h"
  18. #include "Tree.h"
  19.  
  20. #if !defined(__STDC__) && !defined(_NO_PROTO)
  21. #define _NO_PROTO
  22. #endif
  23. #if defined(__STDC__) && defined(_NO_PROTO)
  24. #undef _NO_PROTO
  25. #endif
  26.  
  27. #ifdef __STDC__
  28. # ifndef MISSING_STDARG_H
  29. #  include <stdarg.h>
  30. # endif
  31. # define Va_start(a,b) va_start(a,b)
  32. #else
  33. # include <varargs.h>
  34. # define Va_start(a,b) va_start(a)
  35. #endif
  36.  
  37. #ifndef VAX
  38. #include <pwd.h>
  39. #endif
  40.  
  41. #ifdef EDITRES
  42.     extern void _XEditResCheckMessages();
  43. #endif
  44.  
  45. MidasOperand MidasGetIngot();
  46. MidasOperand MidasGetCreateCallback();
  47. void MidasLoadImage();
  48.  
  49. void MidasDispatchCommandCallback();
  50. MidasOperand MidasEvaluateExpression();
  51.  
  52. #ifndef VAX
  53. WidgetList DXmChildren();
  54. int DXmNumChildren();
  55. #endif
  56.  
  57. /*
  58.  * Global data            
  59.  */                                  
  60.  
  61. Display         *display;        /* Display variable */
  62. XtAppContext    app_context;        /* application context */
  63.  
  64. static Widget WidgetTree = NULL;        
  65. static Widget MidasMain;                /* Root widget ID of main */
  66.                                         /* MRM fetch */
  67.  
  68. #define HASHTABLESIZE 137
  69. static MidasWidget *HashTable[HASHTABLESIZE];
  70.  
  71. struct QueuedCommand {
  72.     Widget                Widget;
  73.     char                 *Command;
  74.     struct QueuedCommand *Next; 
  75. };
  76.  
  77. typedef struct QueuedCommand QueuedCommand;
  78.  
  79. static struct {
  80.     QueuedCommand *Head;
  81.     QueuedCommand *Tail;
  82. } CommandQueue;
  83.  
  84. struct MidasFile {
  85.     MrmHierarchy         Hierarchy;
  86.     Widget               DefaultParent;
  87. };
  88.  
  89. typedef struct MidasFile MidasFile;
  90.  
  91. struct ConvertPair {
  92.     char    *Name;
  93.     char    Value;
  94. };
  95.  
  96. typedef struct ConvertPair ConvertPair;
  97.  
  98. static int ExitResponse;
  99.  
  100. static ConvertPair ConvertBoolean[] = {{"true",1}, 
  101.                                        {"false",0},
  102.                                        {0,0}};
  103.  
  104. static XtConvertArgRec ConvertBooleanArg[] =
  105. {{XtAddress,(XtPointer) ConvertBoolean,sizeof(XtPointer)}};
  106.  
  107. static ConvertPair ConvertPacking[] = {{"XmPACK_TIGHT" ,1},
  108.                                        {"XmPACK_COLUMN",2},
  109.                                        {"XmPACK_NONE"  ,3},
  110.                                        {0,0}};
  111. static XtConvertArgRec ConvertPackingArg[] =
  112. {{XtAddress,(XtPointer) ConvertPacking,sizeof(XtPointer)}};
  113. static XtConvertArgRec ConvertWidgetArg[] = {{XtBaseOffset,0,sizeof(Widget)}};
  114.  
  115. static List   *MidasWidgetList;
  116. static List   *MidasFileList;
  117. static List   *MidasShellList;
  118.  
  119. static XtTranslations MidasTranslations;
  120.  
  121. Widget ActiveWidget;
  122. XmAnyCallbackStruct *ActiveCallback;
  123. Boolean IfState;
  124.  
  125. static char ProblemStrings[2000];
  126. static char *ProblemPtr = ProblemStrings;
  127.  
  128. /* we need some protection here against exceeding the buffer size */
  129.  
  130. jmp_buf JmpEnv[100];
  131. int NumJump = 0; 
  132.  
  133. static Widget MidasFindName();
  134. void *MidasConvertExpression();
  135.  
  136. static XtErrorMsgHandler OldHandler;
  137.  
  138. void MidasDummyHandler(){}
  139. void MidasSuppressXtWarningMessages()
  140. {
  141.   OldHandler = XtAppSetWarningMsgHandler(app_context,MidasDummyHandler);
  142. }
  143. void MidasReenableXtWarningMessages()
  144. {
  145.   XtAppSetWarningMsgHandler(app_context,OldHandler);
  146. }
  147. static char *MidasClassName(w)
  148. Widget w;
  149. {
  150.    CoreClassPart *Class = (CoreClassPart *) XtClass(w);
  151.    return Class->class_name; 
  152. }
  153. Widget MidasGetActiveWidget()
  154. {
  155.   return ActiveWidget;
  156. }
  157. XmString MidasCharToString(C)  /*---Convert a char * to an XmString */
  158.       char *C;
  159. {
  160.     return XmStringCreateSimple(C);
  161. }
  162. #ifndef _NO_PROTO
  163. void MidasError(char *fmt,...)
  164. #else
  165. /* VARARGS2*/
  166. void MidasError(fmt,va_alist)
  167. char *fmt;
  168. va_dcl
  169. #endif
  170. {
  171.     va_list args;
  172.     Va_start(args, fmt);
  173.      
  174.     vsprintf(ProblemPtr, fmt, args);
  175.     printf("Error: %s\n",ProblemPtr);
  176.     ProblemPtr += strlen(ProblemPtr);
  177.     *ProblemPtr++ = '\n';
  178.     va_end(args);
  179.  
  180.     if (NumJump > 0) longjmp(JmpEnv[--NumJump],1);
  181.  
  182.     *--ProblemPtr = '\0';
  183.       {
  184.         Widget w;
  185.         XmString string = XmStringCreateLtoR(ProblemStrings,
  186.                                              XmSTRING_DEFAULT_CHARSET);   
  187.         int n = 0; 
  188.         Arg args[10];
  189.         XtSetArg(args[n],XmNmessageString, string); n++;
  190.  
  191.         w = MidasFindName("MidasErrorBox");
  192.         if (w != 0)
  193.           {
  194.             XtSetValues(w,args,n);
  195.             XtFree(string);
  196.             XtManageChild(w);
  197.           }
  198.       }
  199.     ProblemPtr = ProblemStrings;
  200. };
  201. char *MidasStringToChar(string) /*----Convert an XmString to a char */
  202.      XmString string;
  203. {
  204.     XmStringContext   context;
  205.     char              *result;
  206.     XmStringCharSet   charset;
  207.     XmStringDirection direction;
  208.     Boolean           separator;
  209.  
  210.     XmStringInitContext(&context,string); 
  211.     XmStringGetNextSegment(context,&result,&charset,&direction,&separator); 
  212.     XmStringFreeContext(context);
  213.  
  214.     return result;
  215. };
  216. void MidasScanChildren(w,Rtn,Closure1,Closure2)
  217.       Widget w;
  218.       void (*Rtn)();
  219.       XtPointer Closure1;
  220.       XtPointer Closure2;
  221. {
  222.    int n;
  223.    Widget *list;  
  224.  
  225.    if (XtIsSubclass(w,compositeWidgetClass))
  226.       {
  227.         list = DXmChildren(w);
  228.         n = DXmNumChildren(w);
  229.       
  230.         for (; n > 0; n-- , list++) Rtn(*list,Closure1,Closure2); 
  231.       }
  232.  
  233.    if (SGMLIsCompositeText(w))
  234.       {
  235.         Arg arglist[10];
  236.         int nn = 0;
  237.   
  238.         XtSetArg(arglist[nn],XtNchildren,&list); nn++;
  239.         XtSetArg(arglist[nn],XtNnumChildren,&n); nn++;
  240.         XtGetValues(w,arglist,nn);
  241.         
  242.         for (; n > 0; n-- , list++) Rtn(*list,Closure1,Closure2); 
  243.       }
  244.  
  245.    if (XtIsWidget(w) && w->core.screen != 0)
  246.      {
  247.        list = w->core.popup_list;
  248.        n = w->core.num_popups;       
  249.  
  250.        if (list != NULL) for (; n > 0; n-- , list++) Rtn(*list,Closure1,Closure2); 
  251.      }
  252. }
  253. void MidasScanAncestors(w,Rtn,Closure1)
  254.       Widget w;
  255.       void (*Rtn)();
  256.       XtPointer Closure1;
  257. {
  258.    int n;
  259.    Widget *list;  
  260.  
  261.    Rtn(w,Closure1);
  262.    MidasScanChildren(w,MidasScanAncestors,(XtPointer) Rtn,Closure1);
  263. }
  264. static MrmHierarchy MidasOpenUidFile(name,parent)
  265. char *name;
  266. Widget parent;
  267. {
  268.     MrmHierarchy hierarchy; 
  269.     MidasFile *mfile;
  270.     ListItem *item;
  271.     
  272.     MrmOpenHierarchy(1, &name, NULL, &hierarchy);
  273.     item = MidasAddItemToList(MidasFileList,name);
  274.     mfile = XtNew(MidasFile);
  275.     mfile->DefaultParent = parent;
  276.     mfile->Hierarchy = hierarchy;
  277.     item->Pointer = mfile;
  278.  
  279.     return hierarchy;
  280. }
  281. void MidasWidgetBeingDestroyed(w,mw,reason)
  282.     Widget w;
  283.     MidasWidget *mw;
  284.     MidasWidget **reason;
  285. {
  286.     /* remove from hash chain */ 
  287.  
  288.     int hash = ((int) w) % HASHTABLESIZE;
  289.     MidasWidget *loop = HashTable[hash];
  290.   
  291.     if (loop == mw) HashTable[hash] = mw->HashChain;
  292.     else 
  293.       { 
  294.         for ( ; loop->HashChain != mw; loop = loop->HashChain);
  295.         loop->HashChain = mw->HashChain;  
  296.       }  
  297.  
  298.     if (mw->Map       != NULL) XtDestroyWidget(mw->Map);
  299.     if (mw->IngotList != NULL) MidasDestroyIngots(mw);
  300.     if (mw->NameEntry != NULL) MidasRemoveItemFromList(MidasWidgetList,mw->NameEntry);
  301.     else XtFree((char *) mw);
  302. }
  303. MidasWidget *MidasWidgetToMW(w)
  304. Widget w;
  305. /*
  306.  *  This routine returns a pointer to the MidasWidget structure for any widget.
  307.  */ 
  308. {
  309.     int hash = ((int) w) % HASHTABLESIZE;
  310.     MidasWidget *mw = HashTable[hash];
  311.   
  312.     for ( ; mw != NULL; mw = mw->HashChain)
  313.       if (mw->Widget == w) return mw;
  314.   
  315.     mw = XtNew(MidasWidget);
  316.     mw->Widget       = w;
  317.     mw->ShowChildren = False;
  318.     mw->Map          = NULL;
  319.     mw->IngotList    = NULL;
  320.     mw->Parent       = NULL;
  321.     mw->NameEntry    = NULL;
  322.     mw->HashChain    = HashTable[hash];
  323.     mw->Inited       = FALSE;
  324.     HashTable[hash]  = mw;
  325.  
  326.     return mw;
  327. }
  328. static void MidasRegisterName(name,w)
  329. char *name;
  330. Widget w;
  331. {
  332.     ListItem *item = MidasFindItemInList(MidasWidgetList,name);
  333.     if (item == NULL || ((MidasWidget *) item->Pointer)->Widget != w) 
  334.       {
  335.         MidasWidget *mw = MidasWidgetToMW(w);
  336.  
  337.         item = MidasAddItemToList(MidasWidgetList,name);
  338.         item->Pointer = mw;
  339.         mw->NameEntry = item;
  340.       }
  341. }
  342. static void MidasAddChildTree(Child,mw)
  343. Widget Child;
  344. MidasWidget *mw;
  345. {
  346.   Widget w;
  347.   MidasWidget *newmw = MidasWidgetToMW(Child);
  348.   XmString label; 
  349.   Arg arglist[3];
  350.   int n = 0;
  351.   
  352.   if (WidgetTree == NULL) return; 
  353.  
  354.   label = MidasCharToString(XtName(Child)); 
  355.    
  356.   if (mw != NULL) { XtSetArg(arglist[n],XtNtreeParent,mw->Map); n++; }
  357.   XtSetArg(arglist[n],XmNuserData,Child); n++;
  358.   XtSetArg(arglist[n],XmNlabelString,label); n++;
  359.  
  360.   w = XmCreatePushButton(WidgetTree,"TreeLeaf",arglist,n);
  361.  
  362.   XmStringFree(label);
  363.  
  364.   XtManageChild(w);
  365.   newmw->Map = w;
  366. }   
  367. static void MidasRemoveChildTree(Child)
  368. Widget Child;
  369. {
  370.   MidasWidget *mw = MidasWidgetToMW(Child);
  371.  
  372.   if (mw->ShowChildren) MidasScanChildren(Child,MidasRemoveChildTree,NULL,NULL);
  373.  
  374.   if (mw->Map != NULL) 
  375.     {
  376.       XtDestroyWidget(mw->Map);
  377.       mw->Map = NULL;
  378.     }
  379.   mw->ShowChildren = FALSE;   
  380. }
  381. static void MidasToggleChildrenTree(w)
  382. Widget w;
  383. {
  384.   MidasWidget *mw = MidasWidgetToMW(w);
  385.  
  386.   if (WidgetTree == NULL) return;
  387.  
  388.   mw->ShowChildren = !mw->ShowChildren;
  389.   if (mw->ShowChildren) MidasScanChildren(w,MidasAddChildTree,(XtPointer) mw,NULL);   
  390.   else                  MidasScanChildren(w,MidasRemoveChildTree,NULL,NULL);    
  391. }
  392. void MidasSetupWidget(w)
  393. Widget w;
  394. {
  395.     typedef struct _MR { char *Ingots; char *CreateCallback; } MidasResources;
  396.     MidasResources result;
  397.     MidasWidget *mw = MidasWidgetToMW(w);
  398.     MidasWidget *parent = MidasWidgetToMW(XtParent(w));
  399.     
  400. #define Offset(field) XtOffsetOf(MidasResources,field)
  401.  
  402.     static XtResource resources[] = 
  403.       {{"midasIngots"           ,"MidasIngots"         ,XtRString ,sizeof(char *),
  404.          Offset(Ingots)         ,XtRImmediate          ,NULL},
  405.        {"midasCreateCallback"   ,"MidasCreateCallback" ,XtRString ,sizeof(char *),
  406.          Offset(CreateCallback) ,XtRImmediate          ,NULL}};
  407.  
  408. #undef Offset
  409.     /*
  410.      *  Check if widget already initialized
  411.      */       
  412.  
  413.     if (mw->Inited) return; 
  414.     mw->Inited = TRUE;
  415.      
  416.     /*
  417.      * If the widgets parent has show children (in the widget tree)
  418.      * then make it so
  419.      */
  420.      
  421.     if (parent->ShowChildren) MidasAddChildTree(w,parent);
  422.          
  423.     /*  
  424.      *  Add the special midas translation to all Widget children
  425.      */
  426.  
  427.     if (XtIsWidget(w)) XtOverrideTranslations(w,MidasTranslations);
  428.  
  429.  
  430.     XtAddCallback(w,XtNdestroyCallback,MidasWidgetBeingDestroyed,(XtPointer) mw);
  431.  
  432.     XtGetApplicationResources(w,(XtPointer)&result,resources,XtNumber(resources),NULL,0);
  433.     if (result.Ingots != NULL) MidasSetupIngots(mw,result.Ingots);
  434.     if (result.CreateCallback != NULL) 
  435.       {
  436.         MidasSetIngotString(w,"midasCreateCallback",result.CreateCallback);
  437.         MidasDispatchCommandCallback(w,result.CreateCallback,NULL);
  438.       }
  439. }
  440. Widget MidasCreateWidget(Parent,Class,Name)
  441. Widget Parent;
  442. WidgetClass Class;
  443. char *Name;
  444. {
  445.     Widget w = XtCreateManagedWidget(Name,Class,Parent,NULL,0);
  446.     MidasRegisterName(Name,w);
  447.     MidasSetupWidget(w);
  448.     return w;
  449. }
  450. Widget MidasFetch(name,parent)
  451. char *name;
  452. Widget parent;
  453. {
  454.     MrmType class;
  455.     Widget actualParent, widget = 0;
  456.     MidasFile *mfile;
  457.     ListItem *i;
  458.     Boolean Dialog = MidasGetQualifier("DIALOG");
  459.     static LookingForParent = FALSE;
  460.  
  461.     if (!LookingForParent)
  462.       { 
  463.         LookingForParent = TRUE;
  464.         MidasGetQualifier("PARENT",&parent);
  465.         LookingForParent = FALSE;
  466.       }
  467.  
  468.     for (i=MidasFileList->First; i != 0; i=i->Next)
  469.       {
  470.         mfile = i->Pointer;
  471.         if (parent==0) actualParent = mfile->DefaultParent;
  472.         else           actualParent = parent;
  473.         if (Dialog) 
  474.           {
  475.             Arg args[10];
  476.             int n = 0;
  477.             char *dialogName = strcat(strcpy(XtMalloc(strlen(name)+7),name),"Dialog");
  478.             Widget Dw = XmCreateDialogShell(actualParent,dialogName,NULL,0);
  479.             XtSetArg(args[n],XmNx, 0); n++;
  480.             XtSetArg(args[n],XmNy, 0); n++;
  481.             if (MrmFetchWidgetOverride(mfile->Hierarchy,name,Dw,NULL,
  482.                                        args,n,&widget,&class)
  483.                 ==MrmSUCCESS) 
  484.               {
  485.                 MidasRegisterName(name,widget);
  486.                 MidasScanAncestors(Dw,MidasSetupWidget,NULL); 
  487.                 return widget;
  488.               }
  489.             XtDestroyWidget(Dw);
  490.           }
  491.         else 
  492.           {
  493.             if (MrmFetchWidget(mfile->Hierarchy,name,actualParent,&widget,&class) == MrmSUCCESS) 
  494.               {
  495.                 MidasRegisterName(name,widget);
  496.                 MidasScanAncestors(widget,MidasSetupWidget,NULL); 
  497.                 return widget;
  498.               }
  499.           }
  500.       }
  501.     return 0;
  502. }
  503. Pixmap MidasFetchIcon(name)
  504. char *name;
  505. {
  506.     Pixmap PixMap;
  507.     ListItem *i;
  508.     MidasSuppressXtWarningMessages(); 
  509.  
  510.     for (i=MidasFileList->First; i != 0; i=i->Next)
  511.       {
  512.         MidasFile *mfile = i->Pointer;
  513.         Widget w = mfile->DefaultParent;
  514.         Screen *screen = XtScreen(w);
  515.         Pixel foreground = WhitePixelOfScreen(screen);
  516.         Pixel background = BlackPixelOfScreen(screen);
  517.  
  518.         if (MrmFetchIconLiteral(mfile->Hierarchy,name,
  519.                                 screen, XtDisplay(w),
  520.                                 foreground, background, &PixMap)  
  521.             == MrmSUCCESS)
  522.         { 
  523.           MidasReenableXtWarningMessages();
  524.           /* printf("found icon at %x!!!\n",PixMap); */
  525.           return PixMap;
  526.         } 
  527.       }
  528.     MidasReenableXtWarningMessages();
  529.     /* printf("failed to find icon!!!\n"); */
  530.     return 0;
  531. }
  532. static Widget MidasFindName(name)
  533. char *name;
  534. {
  535.     ListItem *item = MidasFindItemInList(MidasWidgetList,name);
  536.     if (item != 0) 
  537.       {
  538.         MidasWidget *mw = item->Pointer;
  539.         return mw->Widget;
  540.       }
  541.     else 
  542.       {
  543.         return MidasFetch(name,0);
  544.       }
  545. }
  546. void MidasFetchDispatchEvent()
  547. {
  548.     XEvent event;
  549.     XtAppNextEvent(app_context,&event);
  550.     XtDispatchEvent(&event);
  551. }
  552. void MidasGetCallbacks(L,w)
  553. List *L;
  554. Widget w;
  555. {
  556.     unsigned int numResource;
  557.     XtResource *Resource, *R;
  558.  
  559.     WidgetClass Class = XtClass(w);
  560.  
  561.     MidasEmptyList(L);
  562.     MidasAddItemToList(L,"midasCreateCallback");
  563.  
  564.     XtGetResourceList(Class,&Resource,&numResource);
  565.     
  566.     for (R=Resource; numResource-- > 0; R += 1)
  567.       if (strcmp(R->resource_type,"Callback") == 0)
  568.         {
  569.            ListItem *item = MidasAddItemToList(L,R->resource_name);
  570.         }
  571. }
  572. void MidasGetResources(L,w)
  573. List *L;
  574. Widget w;
  575. {
  576.     unsigned int numResource;
  577.     XtResource *Resource, *R;
  578.  
  579.     WidgetClass Class = XtClass(w);
  580.  
  581.     MidasEmptyList(L);
  582.  
  583.     XtGetResourceList(Class,&Resource,&numResource);
  584.     
  585.     for (R=Resource; numResource-- > 0; R += 1)
  586.       if (strcmp(R->resource_type,"Callback") != 0)
  587.         {
  588.            ListItem *item = MidasAddItemToList(L,R->resource_name);
  589.         }
  590. }
  591. MidasOperand MidasGetAppResource(w,ResourceName)
  592. Widget w;
  593. char *ResourceName;
  594. {
  595.     static XtResource resources = 
  596.       {"userData","UserData",XtRString,sizeof(char *),0,XtRString,""};
  597.  
  598.     char *result="";
  599.     MidasOperand Temp;
  600.     XtResource *rt = XtNew(XtResource);
  601.  
  602.     *rt = resources;
  603.     rt->resource_name = XtNewString(ResourceName);
  604.     XtGetApplicationResources(w,(XtPointer) &result,rt,1,NULL,0);
  605.  
  606.     Temp.Value.P = result;
  607.     Temp.Dynamic = FALSE;
  608.     Temp.Type = MString;
  609.  
  610.     return Temp;
  611. }
  612. MidasOperand MidasGetValue(w,ResourceName)
  613. Widget w;
  614. char *ResourceName;
  615. {
  616.     MidasOperand Temp;
  617.     char result[200], *ret;
  618.     unsigned int numResource;
  619.     int notfound = 1;
  620.     XtResource *Resource, *R;
  621.     WidgetClass Class = XtClass(w);
  622.  
  623.  
  624.     /*  Special handling for midasCreateCallback resource
  625.      */
  626.  
  627.     if (strcmp(ResourceName,"midasCreateCallback") == 0) return MidasGetCreateCallback(w);
  628.       
  629.     XtGetResourceList(Class,&Resource,&numResource);
  630.     
  631.     for (R=Resource; numResource-- > 0; R += 1)
  632.       {
  633.         if (strcmp(R->resource_name,ResourceName) == 0)
  634.           {
  635.             notfound = 0;
  636.             if (strcmp(R->resource_type,XtRString) == 0)
  637.               {
  638.                 char *ptr;
  639.                 int n=0;
  640.                 Arg args[10];
  641.                 XtSetArg(args[n],ResourceName,&ptr); n++;
  642.                 XtGetValues(w,args,n);
  643.                 ret = XtNewString(ptr);
  644.               }
  645.             else if (strcmp(R->resource_type,"XmString") == 0)  
  646.               {
  647.                 String ptr;
  648.                 int n=0;
  649.                 Arg args[10];
  650.                 XtSetArg(args[n],ResourceName, &ptr); n++;
  651.                 XtGetValues(w,args,n);
  652.                 if (ptr == 0) ret = XtNewString("");
  653.                 else          ret = MidasStringToChar(ptr);
  654.               }
  655.             else
  656.               {
  657.                 XrmValue from,to;
  658.                 if (strcmp(R->resource_type,"Callback") == 0)  
  659.                   {
  660.                     int n = 0;
  661.                     Arg args[10];
  662.                     XtSetArg(args[n],ResourceName, &from.addr); n++;
  663.                     XtGetValues(w,args,n);
  664.                   }
  665.                 else from.addr = ((char *) w) + R->resource_offset;  
  666.  
  667.                 from.size = R->resource_size; 
  668.                 to.size = 200;
  669.                 to.addr = result;
  670.                 XtConvertAndStore(w,R->resource_type,&from,XtRString,&to);
  671.                 if (to.size > 200)
  672.                   {
  673.                     ret = XtMalloc(to.size);
  674.                     to.addr = ret;
  675.                     XtConvertAndStore(w,R->resource_type,&from,XtRString,&to);
  676.  
  677.                   }
  678.                 else ret = XtNewString(result);
  679.              }
  680.           }
  681.        }
  682.     XtFree((char *)Resource);
  683.     if (notfound) MidasError("Resource %s not found",ResourceName);
  684.     Temp.Value.P = ret;
  685.     Temp.Dynamic = TRUE;
  686.     Temp.Type = MString;
  687.     return Temp;
  688. }
  689. MidasShell *MidasGetShell(w)
  690. Widget w;
  691. {
  692.     MidasShell *ms;
  693.     ListItem *i;
  694.  
  695.     for (; ; w = XtParent(w))
  696.       for (i = MidasShellList->First; i != 0; i = i->Next)
  697.         {
  698.           ms = i->Pointer;
  699.           if (ms->Widget == w) return ms; 
  700.         }
  701. }      
  702. void MidasDispatchAndTrapErrors(command)
  703. char *command;
  704. {
  705.     if (setjmp(JmpEnv[NumJump++]) == 0)
  706.       {
  707.         MidasDispatchCommand(command);
  708.         NumJump--;
  709.       }
  710.     else MidasError("Error interpreting command: %s\n       from widget %s (class %s)"
  711.                     ,command,XtName(ActiveWidget),MidasClassName(ActiveWidget));
  712. }
  713. static void midas_command_proc(w,tag,reason)
  714.     Widget w;
  715.     char *tag;
  716.     XmCommandCallbackStruct *reason;
  717. {
  718.     char *command = MidasStringToChar(reason->value);
  719.     Widget Stack = ActiveWidget;
  720.     Boolean StackIf = IfState;
  721.  
  722.     ActiveWidget = w;
  723.     IfState = FALSE;
  724.     
  725.     MidasDispatchAndTrapErrors(command);
  726.  
  727.     ActiveWidget = Stack;
  728.     IfState = StackIf;
  729.     XtFree(command);
  730. };
  731. void MidasEchoCommand(command)
  732. char *command;
  733. {
  734.     XmString s = MidasCharToString(command);
  735.     Widget w = MidasFindName("MidasCommand");
  736.     if (w != 0) w = XmCommandGetChild(w,XmDIALOG_HISTORY_LIST);
  737.     if (w != 0) 
  738.       {  
  739.         XmListAddItem(w,s,0);
  740.         XmListSetBottomPos(w,0);
  741.       }
  742.     XmStringFree(s);
  743. #ifdef debug
  744.     printf("Executing Command: %s\n",command);
  745. #endif
  746. }
  747. void MidasDispatchCommandCallback(w,tag,reason)
  748.     Widget w;
  749.     char *tag;
  750.     XmAnyCallbackStruct *reason;
  751. {
  752.     char buffer[2000];
  753.     char *p = tag , *q = buffer;
  754.     Widget Stack = ActiveWidget;
  755.     XmAnyCallbackStruct *CStack = reason;
  756.  
  757.     ActiveWidget = w;
  758.     ActiveCallback = reason;    
  759.  
  760.     for (;; p++)
  761.       {
  762.         if (*p == '\n' || *p == ';') 
  763.           {
  764.             *q = '\0';
  765.             if (*buffer != '\0')
  766.               {
  767.                 MidasEchoCommand(buffer);
  768.                 MidasDispatchAndTrapErrors(buffer);
  769.               }
  770.             q = buffer;
  771.           }
  772.         else if (*p == '\0') 
  773.           {
  774.             *q = '\0';
  775.             if (*buffer != '\0')
  776.               {
  777.                 MidasEchoCommand(buffer);
  778.                 MidasDispatchAndTrapErrors(buffer);
  779.               }
  780.             break;
  781.           }
  782.         else if (*p == '%') MidasForceEvaluateExpression(&p,&q);
  783.         else *q++ = *p;
  784.       }
  785.     ActiveWidget = Stack;
  786.     ActiveCallback = CStack;
  787. };
  788. void MidasSendActionProc(w,event,params,num_params)
  789.     Widget w;
  790.     XEvent *event;
  791.     String *params;
  792.     Cardinal *num_params;
  793. {
  794.     MidasDispatchCommandCallback(w,*params,NULL);    
  795. }
  796. void MidasSpecialActionProc(w,event,params,num_params)
  797.     Widget w;
  798.     XButtonEvent *event;
  799.     String *params;
  800.     Cardinal *num_params;
  801. {
  802. /*
  803.  * Check to see if the event really came from some child gadget
  804.  * or insenstive widget
  805.  */    
  806.     Widget OldWidget = 0;
  807.  
  808.     for ( ;w != OldWidget && XtIsComposite(w); )
  809.       {
  810.         Widget *list = DXmChildren(w);
  811.         int n = DXmNumChildren(w);
  812.        
  813.         OldWidget = w;
  814.  
  815.         for (; n>0; n--, list++)
  816.           {
  817.             if (!XtIsWidget(*list) || !XtIsSensitive(*list))
  818.               {
  819.                 Dimension width, height;
  820.                 Position x,y;
  821.                 Arg arglist[4];
  822.                 XtSetArg(arglist[0],XmNx,&x);
  823.                 XtSetArg(arglist[1],XmNy,&y);
  824.                 XtSetArg(arglist[2],XmNwidth ,&width);
  825.                 XtSetArg(arglist[3],XmNheight,&height);
  826.                 XtGetValues(*list,arglist,4);
  827.                 if (event->x >= x && event->x < x+width &&
  828.                     event->y >= y && event->y < y+height) 
  829.                   {
  830.                     w = *list;
  831.                     break;      
  832.                   }
  833.               }
  834.           }
  835.       }
  836.     MidasDispatchCommandCallback(w,*params,NULL);    
  837. }
  838. void MidasQueueCommand(w,Command)
  839. Widget w;
  840. char *Command;
  841. {
  842.     QueuedCommand *QC = XtNew(QueuedCommand);
  843.     QC->Widget = w;
  844.     QC->Command = XtNewString(Command); 
  845.     QC->Next = 0;
  846.     if (CommandQueue.Head == 0) CommandQueue.Head = QC;
  847.     else                        CommandQueue.Tail->Next = QC;
  848.     CommandQueue.Tail = QC;
  849. }
  850. void MidasDispatchQueuedCommands()
  851. {
  852.     QueuedCommand *QC, *Next;
  853.     for (QC = CommandQueue.Head; QC != 0; QC = Next)
  854.       {
  855.         MidasDispatchCommandCallback(QC->Widget, QC->Command, 0);
  856.         XtFree(QC->Command);
  857.         Next = QC->Next;
  858.         XtFree((char *)QC);
  859.       }
  860.    CommandQueue.Head = 0;
  861.    CommandQueue.Tail = 0;
  862. }
  863. void MidasIgnore(Command)
  864. char *Command;
  865. {
  866.     MidasDispatchCommandCallback(ActiveWidget,Command,NULL);
  867. }
  868. void MidasIf(Doit,Command)
  869. Boolean Doit;
  870. char *Command;
  871. {
  872.     if (Doit) MidasDispatchCommandCallback(ActiveWidget,Command,NULL);
  873.     IfState = Doit;
  874. }
  875. void MidasElseIf(Doit,Command)
  876. Boolean Doit;
  877. char *Command;
  878. {
  879.     if (!IfState) MidasIf(Doit,Command);
  880. }
  881. void MidasElse(Command)
  882. char *Command;
  883. {
  884.     if (!IfState) MidasDispatchCommandCallback(ActiveWidget,Command,NULL);
  885. }
  886. void MidasBeep(pcent,w)
  887. int pcent;
  888. Widget w;
  889. {
  890.     if (w == NULL) w = ActiveWidget;
  891.     XBell(XtDisplay(w),pcent);
  892. }
  893.  
  894. /*
  895.  * This procedure will ensure that, if a dialog window is being mapped,
  896.  * its contents become visible before returning.  It is intended to be
  897.  * used just before a bout of computing that doesn't service the display.
  898.  * You should still call XmUpdateDisplay() at intervals during this
  899.  * computing if possible.
  900.  *
  901.  * The monitoring of window states is necessary because attempts to map
  902.  * the dialog are redirected to the window manager (if there is one) and
  903.  * this introduces a significant delay before the window is actually mapped
  904.  * and exposed.  This code works under mwm, twm, uwm, and no-wm.  It
  905.  * doesn't work (but doesn't hang) with olwm if the mainwindow is iconified.
  906.  *
  907.  * The argument to ForceDialog is any widget in the dialog (often it
  908.  * will be the BulletinBoard child of a DialogShell).
  909.  */
  910.  
  911. void MidasForceDialog(w)
  912. Widget w;
  913. {
  914.   Widget diashell, topshell;
  915.   Window diawindow, topwindow;
  916.   Display *dpy;
  917.   XWindowAttributes xwa;
  918.   XEvent event;
  919.   XtAppContext cxt;
  920.  
  921. /* Locate the shell we are interested in.  In a particular instance, you
  922.  * may know these shells already.
  923.  */
  924.  
  925.   for (diashell = w;
  926.        !XtIsShell(diashell);
  927.        diashell = XtParent(diashell))
  928.     ;
  929.  
  930. /* Locate its primary window's shell (which may be the same) */
  931.  
  932.   for (topshell = diashell;
  933.        !XtIsTopLevelShell(topshell);
  934.        topshell = XtParent(topshell))
  935.     ;
  936.  
  937.   if (XtIsRealized(diashell) && XtIsRealized(topshell)) {
  938.     dpy = XtDisplay(topshell);
  939.     diawindow = XtWindow(diashell);
  940.     topwindow = XtWindow(topshell);
  941.     cxt = XtWidgetToApplicationContext(diashell);
  942.  
  943. /* Wait for the dialog to be mapped.  It's guaranteed to become so unless... */
  944.  
  945.     while (XGetWindowAttributes(dpy, diawindow, &xwa),
  946.            xwa.map_state != IsViewable) {
  947.  
  948. /* ...if the primary is (or becomes) unviewable or unmapped, it's
  949.    probably iconified, and nothing will happen. */
  950.  
  951.       if (XGetWindowAttributes(dpy, topwindow, &xwa),
  952.           xwa.map_state != IsViewable)
  953.         break;
  954.  
  955. /* At this stage, we are guaranteed there will be an event of some kind.
  956.    Beware; we are presumably in a callback, so this can recurse. */
  957.  
  958.       XtAppNextEvent(cxt, &event);
  959.       XtDispatchEvent(&event);
  960.     }
  961.   }
  962.  
  963. /* The next XSync() will get an expose event if the dialog was unmapped. */
  964.  
  965.   XmUpdateDisplay(topshell);
  966. }
  967. void MidasSetCursor(w,c)
  968. Widget w;
  969. int c;
  970. {
  971.     Cursor C;
  972.  
  973.     if (c!=0) C = XCreateFontCursor(XtDisplay(w),c);
  974.     else      C = None;
  975.  
  976.     XDefineCursor(XtDisplay(w),XtWindow(w),C);
  977.     XFlush(XtDisplay(w));
  978. }
  979. void MidasSetSensitive(w,Sensitive)
  980. Widget w;
  981. Boolean Sensitive;
  982. {
  983.     XtSetSensitive(w,Sensitive);
  984. }
  985. char *MidasGetWidgetName(w)
  986. Widget w;
  987. {
  988.     char *parent, *thisone, *new;
  989.     int pl, tl;
  990.     MidasShell *ms = MidasGetShell(w);
  991.  
  992.     thisone = XtName(w);
  993.     if (*thisone == '\0' || strchr(thisone,'-') != 0)
  994.       MidasError("Can not STORE RESOURCE for unnamed widget");
  995.  
  996.     parent = XtName(ms->Widget);
  997.     pl = strlen(parent);
  998.     tl = strlen(thisone);
  999.     new = XtMalloc(pl+tl+2);
  1000.  
  1001.     strcpy(new,parent);
  1002.     if (ms->Widget != w)
  1003.       {
  1004.         strcat(new,"*");
  1005.         strcat(new,thisone);
  1006.       }
  1007.  
  1008.     return new;
  1009. }
  1010. void MidasSetValue(w,ResourceName,Op)
  1011. Widget w;
  1012. char *ResourceName;
  1013. MidasOperand *Op;
  1014. {
  1015.     char *result;
  1016.     unsigned int numResource;
  1017.     int found = FALSE;
  1018.     XtResource *Resource, *R;
  1019.     WidgetClass Class = XtClass(w);
  1020.  
  1021.     if (strcmp(ResourceName,"midasCreateCallback") == 0) 
  1022.       {
  1023.         MidasSetIngotP(w,ResourceName,Op);
  1024.         return;
  1025.       }
  1026.  
  1027.     XtGetResourceList(Class,&Resource,&numResource);
  1028.  
  1029.     for (R=Resource; numResource-- > 0; R += 1)
  1030.       {    
  1031.         if (strcmp(R->resource_name,ResourceName) == 0)
  1032.           {
  1033.             Arg arglist[1];
  1034.  
  1035.             found = TRUE;
  1036.                  
  1037.             MidasConvertOperand(Op,R->resource_type);
  1038.             XtSetArg(arglist[0],ResourceName,Op->Value.P);
  1039.             XtSetValues(w,arglist,1);              
  1040.  
  1041.             break;
  1042.           }
  1043.       }
  1044.  
  1045.     XtFree((char *) Resource);
  1046.     if (!found) MidasError("Resource %s not found",ResourceName);
  1047. }
  1048. static void MidasStoreAppResource(w,resource,value)
  1049. Widget w;
  1050. char *resource;
  1051. char *value;
  1052. {
  1053.     char *name = MidasGetWidgetName(w);
  1054.     char *new = XtMalloc(strlen(name)+strlen(resource)+2);
  1055.     MidasShell *ms = MidasGetShell(w);
  1056.  
  1057.     strcpy(new,name);
  1058.     strcat(new,".");
  1059.     strcat(new,resource);
  1060.  
  1061.     XrmPutStringResource(&ms->Database,new,value);
  1062.     ms->Changes++;
  1063.  
  1064.     XtFree(new);
  1065.     XtFree(name);
  1066. }
  1067. static void MidasStoreResource(w,resource)
  1068. Widget w;
  1069. char *resource;
  1070. {
  1071.     MidasOperand Temp;
  1072.     Temp = MidasGetValue(w,resource);
  1073.  
  1074.     if (strcmp(Temp.Type,MString)) MidasConvertOperand(Temp,MString);
  1075.    
  1076.     MidasStoreAppResource(w,resource,Temp.Value.P);
  1077.     if (Temp.Dynamic) XtFree(Temp.Value.P);
  1078. }
  1079. static void MidasSaveStoredResources(w)
  1080. Widget w;
  1081. {
  1082.     MidasShell *ms = MidasGetShell(w);
  1083.     XrmPutFileDatabase(ms->Database, ms->Filename);
  1084.     ms->Changes = 0; 
  1085. }
  1086. static void MidasSaveGeometry(w)
  1087. Widget w;
  1088. {
  1089.     MidasStoreResource(w,XmNx);
  1090.     MidasStoreResource(w,XmNy);
  1091.     MidasStoreResource(w,XmNwidth);
  1092.     MidasStoreResource(w,XmNheight);
  1093.     MidasSaveStoredResources(w);        
  1094. }
  1095. static void MidasHelpOnContext(w)
  1096. Widget w;
  1097. {
  1098.     MidasShell *ms = MidasGetShell(w);
  1099.     Cursor C =  XCreateFontCursor(XtDisplay(w),XC_question_arrow);
  1100.     Widget new = XmTrackingLocate(ms->Widget,C,FALSE);
  1101.  
  1102.     for (; new != NULL; new = XtParent(new))
  1103.       if (XtHasCallbacks(new,XmNhelpCallback) == XtCallbackHasSome)
  1104.         {
  1105.           XtCallCallbacks(new,XmNhelpCallback,NULL);
  1106.           break;
  1107.         }
  1108.     XFreeCursor(XtDisplay(w),C);
  1109. static MidasOperand MidasInt(f)
  1110. float f;
  1111. {
  1112.     MidasOperand Temp;
  1113.     Temp.Dynamic = FALSE;
  1114.     Temp.Type = MInt;
  1115.     Temp.Value.I = (int) f;
  1116.     return Temp;
  1117. }
  1118. static void MidasSetFlag(w,flag)
  1119. Widget w;
  1120. int *flag;
  1121. {
  1122.   *flag = 1;
  1123. }
  1124. static MidasOperand MidasHasChildren(w)
  1125. Widget w;
  1126. {
  1127.     MidasOperand Temp;
  1128.     Temp.Dynamic = FALSE;
  1129.     Temp.Type = MBoolean;
  1130.     Temp.Value.I = FALSE;
  1131.   
  1132.     MidasScanChildren(w,MidasSetFlag,(XtPointer) &Temp.Value.I,NULL); 
  1133.     return Temp;
  1134. }
  1135. static MidasOperand MidasChildrenInTree(w)
  1136. Widget w;
  1137. {
  1138.     MidasOperand Temp;
  1139.     MidasWidget *mw = MidasWidgetToMW(w);
  1140.     Temp.Dynamic = FALSE;
  1141.     Temp.Type = MBoolean;
  1142.     Temp.Value.I = mw->ShowChildren;
  1143.     
  1144.     return Temp; 
  1145. }
  1146. static MidasOperand MidasStrnspn(s,t)
  1147. char *s;
  1148. char *t;
  1149. /*
  1150.     Exceedingly temporary
  1151. */
  1152. {
  1153.     MidasOperand Temp;
  1154.     char *p = s;
  1155.     for (;*p != '\0' && *p == ' '; p++);
  1156.     for (;*p != '\0' && *p != ' '; p++);
  1157.     *p = '\0';
  1158.  
  1159.     Temp.Dynamic = TRUE;
  1160.     Temp.Type = MString;
  1161.     Temp.Value.P = (XtPointer) XtNewString(s);
  1162.  
  1163.     return Temp;
  1164. }
  1165. static MidasOperand MidasGetWidgetId(w)
  1166. Widget w;
  1167. {
  1168.     MidasOperand Temp;
  1169.     Temp.Dynamic = FALSE;
  1170.     Temp.Type = MInt;
  1171.     Temp.Value.I = (int) w;
  1172.     return Temp;
  1173. }
  1174. static MidasOperand MidasIsManaged(w)
  1175. Widget w;
  1176. {
  1177.     MidasOperand Temp;
  1178.     int result = XtIsManaged(w);
  1179.     Temp.Dynamic = FALSE;
  1180.     Temp.Type = MBoolean;
  1181.     Temp.Value.I = (result != 0); 
  1182.     return Temp;
  1183. }
  1184. static MidasOperand MidasIsRealized(w)
  1185. Widget w;
  1186. {
  1187.     MidasOperand Temp;
  1188.     int result = XtIsRealized(w);
  1189.     Temp.Dynamic = FALSE;
  1190.     Temp.Type = MBoolean;
  1191.     Temp.Value.I = (result != 0); 
  1192.     return Temp;
  1193. }
  1194. static MidasOperand MidasGetOperandType(Op)
  1195. MidasOperand *Op;
  1196. {
  1197.     MidasOperand Temp;
  1198.  
  1199.     Temp.Dynamic = FALSE;
  1200.     Temp.Type = MString;
  1201.     Temp.Value.P = Op->Type;
  1202.     return Temp;
  1203. }
  1204. static MidasOperand MidasWidgetFunction(w)
  1205. Widget w;
  1206. {
  1207.     MidasOperand Temp;
  1208.     Temp.Dynamic = FALSE;
  1209.     Temp.Type = MWidget;
  1210.     Temp.Value.P = (XtPointer) w;
  1211.     return Temp;
  1212. }
  1213. static MidasOperand MidasFetchFunction(name,parent)
  1214. char *name;
  1215. Widget parent;
  1216. {
  1217.     MidasOperand Temp;
  1218.     Temp.Dynamic = FALSE;
  1219.     Temp.Type = MWidget;
  1220.     Temp.Value.P = (XtPointer) MidasFetch(name,parent);
  1221.     return Temp;
  1222. }
  1223. static MidasOperand MidasParent(w)
  1224. Widget w;
  1225. {
  1226.     MidasOperand Temp;
  1227.     Temp.Dynamic = FALSE;
  1228.     Temp.Type = MWidget;
  1229.     Temp.Value.P = (XtPointer) XtParent(w);
  1230.     return Temp;
  1231. }
  1232. static MidasOperand MidasShellFunction(w)
  1233. Widget w;
  1234. {
  1235.     MidasOperand Temp;
  1236.     MidasShell *ms = MidasGetShell(w);
  1237.  
  1238.     Temp.Dynamic = FALSE;
  1239.     Temp.Type = MWidget;
  1240.     Temp.Value.P = (XtPointer) ms->Widget;
  1241.     return Temp;
  1242. }
  1243. static MidasOperand MidasWidgetName(w)
  1244. Widget w;
  1245. {
  1246.     MidasOperand Temp;
  1247.     char *name = XtName(w); 
  1248.   
  1249.     if (*name == '\0') 
  1250.       {
  1251.         name = XtMalloc(24);
  1252.         sprintf(name,"No Name (%d)",w);
  1253.         Temp.Dynamic = TRUE;
  1254.       }
  1255.     else Temp.Dynamic = FALSE;
  1256.  
  1257.     Temp.Value.P = name;
  1258.     Temp.Type = MString;
  1259.     return Temp;
  1260. }
  1261. static MidasOperand MidasWidgetClass(w)
  1262. Widget w;
  1263. {
  1264.     MidasOperand Temp;
  1265.     Temp.Dynamic = FALSE;
  1266.     Temp.Type = MString;
  1267.     Temp.Value.P = MidasClassName(w);
  1268.     return Temp;
  1269. }
  1270. static MidasOperand MidasGetCommand()
  1271. {
  1272.     MidasOperand Temp;
  1273.     XmCommandCallbackStruct *cb = (XmCommandCallbackStruct *) ActiveCallback;
  1274.  
  1275.     if (ActiveCallback->reason != XmCR_COMMAND_ENTERED) 
  1276.       MidasError("GETCOMMAND requires callback reason XmCR_COMMAND_ENTERED");
  1277.  
  1278.     Temp.Dynamic = TRUE;
  1279.     Temp.Type = MString;
  1280.     Temp.Value.P = MidasStringToChar(cb->value);
  1281.     return Temp;
  1282. }
  1283. static MidasOperand MidasGetClickCount()
  1284. {
  1285.     MidasOperand Temp;
  1286.     XmPushButtonCallbackStruct *cb = (XmPushButtonCallbackStruct *) ActiveCallback;
  1287.     if (ActiveCallback->reason != XmCR_ACTIVATE) 
  1288.       MidasError("GETCLICKCOUNT requires callback reason XmCR_ACTIVATE");
  1289.   
  1290.     Temp.Dynamic = FALSE;
  1291.     Temp.Type = MInt;
  1292.     Temp.Value.I = cb->click_count;
  1293.     return Temp;
  1294. }
  1295. static MidasOperand MidasHyperGetText()
  1296. {
  1297.     MidasOperand Temp;
  1298.     SGMLHyperCallbackStruct *cb = (SGMLHyperCallbackStruct *) ActiveCallback;
  1299. /*
  1300.     if (ActiveCallback->reason != SGMLHYPER_REASON)
  1301.       MidasError("HYPERGETTEXT requires callback reason SGMLHYPER_REASON");
  1302. */
  1303.     Temp.Dynamic = TRUE;
  1304.     Temp.Type = MString;
  1305.     Temp.Value.P = XtNewString(cb->text);
  1306.     return Temp;
  1307. }
  1308. static MidasOperand MidasHyperGetHidden()
  1309. {
  1310.     MidasOperand Temp;
  1311.     SGMLHyperCallbackStruct *cb = (SGMLHyperCallbackStruct *) ActiveCallback;
  1312. /*
  1313.     if (ActiveCallback->reason != SGMLHYPER_REASON)
  1314.       MidasError("HYPERGETTEXT requires callback reason SGMLHYPER_REASON");
  1315. */
  1316.     Temp.Dynamic = TRUE;
  1317.     Temp.Type = MString;
  1318.     Temp.Value.P = XtNewString(cb->hidden);
  1319.     return Temp;
  1320. }
  1321. static MidasOperand MidasHyperGrep(w,string)
  1322. Widget w;
  1323. char *string;
  1324. {
  1325.     MidasOperand Temp;
  1326.     Boolean result = SGMLHyperGrep(w,string,TRUE,FALSE,TRUE);
  1327.  
  1328.     Temp.Value.I = result;
  1329.     Temp.Type = MBoolean;
  1330.     Temp.Dynamic = FALSE;
  1331.     return Temp;
  1332. }
  1333. #ifndef VAX
  1334. static String MidasGetRootDirName(buf)
  1335. String buf;
  1336. {
  1337. #ifndef X_NOT_POSIX
  1338.      uid_t uid;
  1339. #else
  1340.      int uid;
  1341.      extern int getuid();
  1342. #ifndef SYSV386
  1343.      extern struct passwd *getpwuid(), *getpwnam();
  1344. #endif
  1345. #endif
  1346.      struct passwd *pw;
  1347.      static char *ptr = NULL;
  1348.  
  1349.      if (ptr == NULL) {
  1350.     if (!(ptr = getenv("HOME"))) {
  1351.         if (ptr = getenv("USER")) pw = getpwnam(ptr);
  1352.         else {
  1353.         uid = getuid();
  1354.          pw = getpwuid(uid);
  1355.         }
  1356.         if (pw) ptr = pw->pw_dir;
  1357.         else {
  1358.         ptr = NULL;
  1359.         *buf = '\0';
  1360.         }
  1361.     }
  1362.      }
  1363.  
  1364.      if (ptr)
  1365.      (void) strcpy(buf, ptr);
  1366.  
  1367.      buf += strlen(buf);
  1368.      *buf = '/';
  1369.      buf++;
  1370.      *buf = '\0';
  1371.      return buf;
  1372. }
  1373. #endif
  1374. static char* MidasGetAppUserDefaults(dpy,name)
  1375. Display *dpy;
  1376. char *name;
  1377. {
  1378.     char *filename;
  1379. #ifdef VAX
  1380.  
  1381.     static char file[] = "DECW$USER_DEFAULTS:", ext[] = ".DAT"; 
  1382.     int totlen;
  1383.  
  1384.     totlen = strlen(file) + strlen(ext) + strlen(name) + 1;
  1385.     filename = XtMalloc(totlen);
  1386.     strcpy(filename,file);
  1387.     strcat(filename,name);
  1388.     strcat(filename,ext);
  1389.  
  1390. #else
  1391.  
  1392.     char* path;
  1393.     Boolean Alloc=False;
  1394.     char homedir[256];
  1395.     MidasGetRootDirName(homedir);
  1396.  
  1397.     if (!(path = getenv("XUSERFILESEARCHPATH"))) {
  1398.     char *old_path;
  1399.     if (!(old_path = getenv("XAPPLRESDIR"))) {
  1400.         char *path_default = "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N";
  1401.         path = XtMalloc(6*strlen(homedir) + strlen(path_default));
  1402.         sprintf( path, path_default,
  1403.             homedir, homedir, homedir, homedir, homedir, homedir );
  1404.     } else {
  1405.         char *path_default = "%s/%%L/%%N%%C:%s/%%l/%%N%%C:%s/%%N%%C:%s/%%N%%C:%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N";
  1406.         path = XtMalloc( 6*strlen(old_path) + 2*strlen(homedir) + strlen(path_default));
  1407.         sprintf(path, path_default, old_path, old_path, old_path, homedir,
  1408.             old_path, old_path, old_path, homedir );
  1409.     }
  1410.         Alloc=True;
  1411.     }
  1412.     filename = XtResolvePathname(dpy,NULL,name,NULL,path,NULL,0,NULL);
  1413.     if (!filename) 
  1414.       {
  1415.          filename = XtMalloc(strlen(homedir)+strlen(name)+1);
  1416.          strcpy(filename,homedir);
  1417.          strcat(filename,name); 
  1418.       }
  1419.     if (Alloc) XtFree(path);
  1420.  
  1421. #endif
  1422.    return filename;
  1423. }
  1424. Widget MidasCreateDialog(name)
  1425. char *name;
  1426. {
  1427.     Widget parent, dialog;
  1428.     if (MidasGetQualifier("PARENT",&parent) == 0) MidasError("Parent required");
  1429.     dialog = XmCreateDialogShell(parent,name,NULL,0);
  1430.     MidasRegisterName(name,dialog);
  1431.     return dialog;
  1432. }
  1433. Widget MidasCreateShellArg(name,argv,argc)
  1434. char *name;
  1435. String *argv;
  1436. Cardinal *argc;
  1437. {
  1438.     int totlen; 
  1439.     char *new;
  1440.     ListItem *item;
  1441.     MidasShell *ms = XtNew(MidasShell);
  1442.     char *ShellName = XtNewString(name);
  1443.     char *ShellClass = XtNewString(name);
  1444.     char *uidfile;
  1445.     Pixmap icon;
  1446.     Widget w;
  1447.  
  1448.     *ShellName = tolower(*ShellName);
  1449.     *ShellClass = toupper(*ShellClass);
  1450.  
  1451.     display = XtOpenDisplay(app_context,NULL,NULL,ShellClass,
  1452.                         NULL, 0, argc, argv);
  1453.     if (display == 0) { MidasError("Could not open display"); exit(0); }
  1454.  
  1455.     w = XtAppCreateShell(ShellName,ShellClass,
  1456.                          applicationShellWidgetClass,
  1457.                          display, NULL, 0);
  1458.    
  1459.     new = MidasGetAppUserDefaults(display,ShellClass);
  1460.  
  1461.     XtFree(ShellName);
  1462.     XtFree(ShellClass);
  1463.  
  1464.     item = MidasAddItemToList(MidasShellList,name);
  1465.     item->Pointer = ms;
  1466.  
  1467.     ms->Widget = w;
  1468.     ms->Database = XrmGetFileDatabase(new);
  1469.     ms->Filename = new;
  1470.     ms->Changes = 0; 
  1471.  
  1472.     MidasSetupWidget(w);
  1473.     MidasRegisterName(name,w);
  1474.  
  1475.     if (MidasGetQualifier("UIDFILE",&uidfile)) MidasOpenUidFile(uidfile,w);
  1476.     if (MidasGetQualifier("ICON",&icon)) 
  1477.       { 
  1478.         int n = 0;
  1479.         Arg args[10];
  1480.         XtSetArg(args[n],XmNiconPixmap, icon); n++;
  1481.         XtSetValues(w, args, n);
  1482.       }
  1483. #ifdef EDITRES
  1484.     XtAddEventHandler(w, (EventMask)0, True,
  1485.                   _XEditResCheckMessages, (XtPointer)NULL);
  1486. #endif
  1487.  
  1488.     /* Shells are always displayed in the Widget Tree */
  1489.     
  1490.     MidasAddChildTree(w,NULL);
  1491.  
  1492.     return w;
  1493. }
  1494. Widget MidasCreateShell(name)
  1495. char *name;
  1496. {
  1497.   Cardinal zilch=0;
  1498.   return MidasCreateShellArg(name,NULL,&zilch);
  1499. }
  1500. static MidasOperand MidasTreeToWidget(w)
  1501. Widget w;
  1502. {
  1503.   MidasOperand Temp;
  1504.   Arg arglist[1];
  1505.   XtSetArg(arglist[0],XmNuserData,&Temp.Value.P);
  1506.   XtGetValues(w,arglist,1);
  1507.   
  1508.   Temp.Type = MWidget;
  1509.   Temp.Dynamic = FALSE;
  1510.    
  1511.   return Temp;
  1512. }
  1513. void MidasCreateWidgetTree(Tree)
  1514. Widget Tree;
  1515. {
  1516.   ListItem *item;
  1517.  
  1518.   WidgetTree = Tree;
  1519.  
  1520.   for (item = MidasShellList->First; item != 0; item = item->Next)
  1521.     {
  1522.       MidasShell *ms = (MidasShell *) item->Pointer;
  1523.       MidasAddChildTree(ms->Widget,NULL);   
  1524.     }   
  1525. }
  1526. static void MidasInvertWidget(w)
  1527. Widget w;
  1528.   Arg arglist[2];
  1529.   Pixel fg; 
  1530.   Pixel bg;  
  1531.  
  1532.   XtSetArg(arglist[0],XmNforeground,&fg);
  1533.   XtSetArg(arglist[1],XmNbackground,&bg);
  1534.   XtGetValues(w,arglist,2);
  1535.  
  1536.   XtSetArg(arglist[0],XmNforeground,bg);
  1537.   XtSetArg(arglist[1],XmNbackground,fg);
  1538.   XtSetValues(w,arglist,2);
  1539. }
  1540. static void MidasCurrentWidgetInTree(w)
  1541. Widget w;
  1542. {
  1543.   static Widget OldWidget = NULL;
  1544.   Widget TreeW; 
  1545.   MidasWidget *mw, *parent;
  1546.   
  1547.   if (OldWidget != NULL)
  1548.     {
  1549.       mw = MidasWidgetToMW(OldWidget);
  1550.       TreeW = mw->Map;
  1551.       if (TreeW != NULL) MidasInvertWidget(TreeW);
  1552.     }
  1553.   OldWidget = w;
  1554.   
  1555.   mw = MidasWidgetToMW(w); 
  1556.  
  1557.   /* if this widget isnt in the tree, make it so */ 
  1558.  
  1559.   for (; mw->Map  == NULL; )
  1560.     {
  1561.       for (parent = mw; parent->Map == NULL ; parent = MidasWidgetToMW(XtParent(parent->Widget)) );
  1562.       MidasToggleChildrenTree(parent->Widget); 
  1563.     }
  1564.  
  1565.   TreeW = mw->Map;
  1566.   MidasInvertWidget(TreeW); 
  1567.  
  1568.   /* it may be necessary to scroll the tree to make this widget visible */
  1569.  
  1570.   {
  1571.      Arg arglist[10];
  1572.      int n=0;
  1573.      Widget h_scroll, v_scroll;
  1574.   
  1575.      Widget Tree = XtParent(TreeW);
  1576.      Widget Clip = XtParent(Tree);
  1577.      Widget Swin = XtParent(Clip);
  1578.  
  1579.      Position    x_button,y_button;
  1580.      Dimension   h_button,w_button;
  1581.      Position    x_clip,y_clip;
  1582.      Dimension   h_clip,w_clip;
  1583.      Position    dv=0,dh=0;
  1584.      int min,max;
  1585.      int v_val,v_size,v_inc,v_page;
  1586.      int h_val,h_size,h_inc,h_page;
  1587.      Position x,y;
  1588.  
  1589.     /* Get window scroll bars */
  1590.  
  1591.      XtSetArg(arglist[n],XmNhorizontalScrollBar, &h_scroll); n++;
  1592.      XtSetArg(arglist[n],XmNverticalScrollBar,   &v_scroll); n++;
  1593.      XtGetValues(Swin,arglist,n);
  1594.       
  1595.     /* Get size of clip window and button */
  1596.  
  1597.      n = 0;
  1598.      XtSetArg(arglist[n],XmNwidth,  &w_clip); n++;
  1599.      XtSetArg(arglist[n],XmNheight, &h_clip); n++;
  1600.      XtGetValues(Clip,arglist,n);
  1601.  
  1602.      n = 0;
  1603.      XtSetArg(arglist[n],XmNwidth,  &w_button); n++;
  1604.      XtSetArg(arglist[n],XmNheight, &h_button); n++;
  1605.      XtGetValues(TreeW,arglist,n);
  1606.  
  1607.     /* Get global coordinates of clip and selection rect */
  1608.  
  1609.      XtTranslateCoords(Clip,0,0,&x_clip,&y_clip);
  1610.      XtTranslateCoords(TreeW,0,0,&x_button,&y_button);
  1611.  
  1612.     /* offset of selection within clip window */
  1613.  
  1614.      x = x_button - x_clip;
  1615.      y = y_button - y_clip;
  1616.  
  1617.     /* selection y coordinate is not visible */
  1618.  
  1619.      if( y < 0 || y + h_button > h_clip)
  1620.      {
  1621.         /* the widget must be moved verticaly by dv pixels */
  1622.  
  1623.         dv = (y + h_button / 2)  - h_clip / 2;
  1624.  
  1625.         n = 0;
  1626.         XtSetArg(arglist[n],XmNminimum,&min); n++;
  1627.         XtSetArg(arglist[n],XmNmaximum,&max); n++;
  1628.  
  1629.         XtGetValues(v_scroll,arglist,n);
  1630.  
  1631.         XmScrollBarGetValues(v_scroll,&v_val,&v_size,&v_inc,&v_page);
  1632.  
  1633.         max -= v_size;
  1634.  
  1635.         if( dv + v_val > max ) dv = max - v_val;
  1636.         if( dv + v_val < min ) dv = min - v_val;
  1637.      }
  1638.  
  1639.     /* selection x coordinate is not visible */
  1640.  
  1641.      if( x < 0 || x + w_button > w_clip)
  1642.      {
  1643.         /* the widget must be moved horizontaly by dh pixels */
  1644.  
  1645.         dh = (x + w_button / 2)  - w_clip / 2;
  1646.  
  1647.         n = 0;
  1648.         XtSetArg(arglist[n],XmNminimum,&min); n++;
  1649.         XtSetArg(arglist[n],XmNmaximum,&max); n++;
  1650.         XtGetValues(h_scroll,arglist,n);
  1651.  
  1652.         XmScrollBarGetValues(h_scroll,&h_val,&h_size,&h_inc,&h_page);
  1653.  
  1654.         max -= h_size;
  1655.  
  1656.         if( dh + h_val > max ) dh = max - h_val;
  1657.         if( dh + h_val < min ) dh = min - h_val;
  1658.  
  1659.      }
  1660.  
  1661.     /* if the widget must be moved */
  1662.  
  1663.      if(dv || dh)
  1664.      {
  1665.         Position x,y;
  1666.   
  1667.         n = 0;
  1668.         XtSetArg(arglist[n],XmNx,&x); n++;
  1669.         XtSetArg(arglist[n],XmNy,&y); n++;
  1670.         XtGetValues(Tree,arglist,n);
  1671.  
  1672.         x -= dh;
  1673.         y -= dv;
  1674.  
  1675.         /* move it */
  1676.  
  1677.         n = 0;
  1678.         XtSetArg(arglist[n],XmNx,x); n++;
  1679.         XtSetArg(arglist[n],XmNy,y); n++;
  1680.         XtSetValues(Tree,arglist,n);
  1681.  
  1682.         /* update scroll bars */
  1683.  
  1684.         if(dv) XmScrollBarSetValues(v_scroll,v_val+dv,v_size,v_inc,
  1685.             v_page,TRUE);
  1686.         if(dh) XmScrollBarSetValues(h_scroll,h_val+dh,h_size,h_inc,
  1687.             h_page,TRUE);
  1688.  
  1689.       }
  1690.     }
  1691.  
  1692. }
  1693. Widget MidasTraceWidgetTree(root,path)
  1694. Widget root;
  1695. char *path;
  1696. {
  1697.     Widget w = root;
  1698.  
  1699.     if (strcmp(path,"") ==  0) return w;
  1700.     else if (strncmp("^^^",path,3) == 0) 
  1701.       {
  1702.         path += 3;
  1703.         for (w = XtParent(w); w != 0; w = XtParent(w)) 
  1704.           {
  1705.             Widget result = MidasTraceWidgetTree(w,path);
  1706.             if (result != 0) return result;
  1707.           }
  1708.         return 0;
  1709.       }
  1710.     else if (*path == '^') 
  1711.       {
  1712.         path += 1;
  1713.         w = XtParent(w);
  1714.         return MidasTraceWidgetTree(w,path);
  1715.       }
  1716.     else if (strncmp("...",path,3) == 0) 
  1717.       {
  1718.         Widget *list, *save;  
  1719.         int n , nsave;
  1720.       
  1721.         if (XtIsSubclass(w,compositeWidgetClass) != 0)
  1722.           { 
  1723.  
  1724.             save = DXmChildren(w);  
  1725.             nsave = DXmNumChildren(w);
  1726.  
  1727.             path += 3; 
  1728.             for (list = save , n = nsave; n > 0; n-- , list++) 
  1729.               { 
  1730.                 Widget result = MidasTraceWidgetTree(*list,path);
  1731.                 if (result != 0) return result;
  1732.               }
  1733.             path -= 3;
  1734.             for (list = save , n = nsave; n > 0; n-- , list++) 
  1735.               { 
  1736.                 Widget result = MidasTraceWidgetTree(*list,path);
  1737.                 if (result != 0) return result;
  1738.               }
  1739.           }
  1740.         if (XtIsWidget(w))
  1741.           {
  1742.             save = w->core.popup_list;
  1743.             nsave = w->core.num_popups;       
  1744.        
  1745.             for (list = save , n = nsave; n > 0; n-- , list++) 
  1746.               { 
  1747.                 Widget result = MidasTraceWidgetTree(*list,path);
  1748.                 if (result != 0) return result;
  1749.               }
  1750.             return 0;
  1751.           }
  1752.       }
  1753.     else if (*path == '.') 
  1754.       {
  1755.         Widget *list;  
  1756.         int n;  
  1757.       
  1758.         if (XtIsSubclass(w,compositeWidgetClass) == 0) return 0;
  1759.  
  1760.         list = DXmChildren(w); 
  1761.         n = DXmNumChildren(w);   
  1762.  
  1763.         path += 1;
  1764.         for (; n > 0; n-- , list++) 
  1765.           { 
  1766.             Widget result = MidasTraceWidgetTree(*list,path);
  1767.             if (result != 0) return result;
  1768.           }
  1769.         return 0;
  1770.       }
  1771.     else
  1772.       {
  1773.         char temp, *p, *e = 0;
  1774.  
  1775.         for (p=path; *p != '.' && *p != '^' && *p != '\0'; p++) 
  1776.           {
  1777.             if (*p == '=') e = p;
  1778.           }
  1779.  
  1780.         temp = *p;
  1781.         *p = '\0';               
  1782.  
  1783.  
  1784.         if (e == 0)
  1785.           {
  1786.             if (strcmp(path,"*") == 0) 
  1787.               {
  1788.                 *p = temp;
  1789.                 return MidasTraceWidgetTree(w,p);
  1790.               }
  1791.             else
  1792.               {
  1793.                 if (strcmp(XtName(w),path) == 0)
  1794.                   {
  1795.                     *p = temp;
  1796.                     return MidasTraceWidgetTree(w,p);
  1797.                   }
  1798.                 else if (strcmp(MidasClassName(w),path) == 0)
  1799.                   {
  1800.                     *p = temp;
  1801.                     return MidasTraceWidgetTree(w,p);
  1802.                   }
  1803.                 else
  1804.                   {
  1805.                     *p = temp;
  1806.                     return 0;
  1807.                   }
  1808.               }
  1809.           }
  1810.         else
  1811.           {
  1812.             unsigned int numResource;
  1813.             XtResource *Resource, *R;
  1814.             WidgetClass Class = XtClass(w);
  1815.  
  1816.             XtGetResourceList(Class,&Resource,&numResource);
  1817.     
  1818.             *e = '\0';
  1819.  
  1820.             for (R=Resource; numResource-- > 0; R += 1)
  1821.               if (strcmp(R->resource_name,path) == 0)
  1822.                 {
  1823.                   XtPointer ptr , result;
  1824.                   XrmValue from,to;
  1825.                   int n = 0;
  1826.                   Arg args[10];
  1827.                   XtSetArg(args[n],path,&result); n++;
  1828.  
  1829.                   XtGetValues(w, args, n);
  1830.                   *e = '=';
  1831.                   *p = temp;
  1832.  
  1833.                   from.size = strlen(e+1)+1; 
  1834.                   from.addr = e+1;
  1835.                   to.size = sizeof(XtArgVal);
  1836.                   to.addr = (XtPointer) &ptr;
  1837.                   XtConvertAndStore(w,XtRString,&from,R->resource_type,&to);
  1838.                   if (to.size > sizeof(XtArgVal)) 
  1839.                   {
  1840.                     Widget res;
  1841.                     XtPointer ptr = XtMalloc(to.size);
  1842.                     to.addr = ptr;
  1843.                     XtConvertAndStore(w,XtRString,&from,R->resource_type,&to);
  1844.  
  1845.                     if (memcmp(to.addr,result,to.size) == 0) 
  1846.                       res = MidasTraceWidgetTree(w,p);
  1847.                     else res = NULL;
  1848.  
  1849.                     XtFree((char *) ptr);
  1850.                     return res;
  1851.                   }
  1852.                 else
  1853.                   {
  1854.                     if (memcmp(to.addr,result,to.size) == 0) 
  1855.                       return MidasTraceWidgetTree(w,p);
  1856.                     else return 0;
  1857.                   }
  1858.                 } 
  1859.  
  1860.             *e = '=';
  1861.             *p = temp;
  1862.  
  1863.             return 0;
  1864.           }
  1865.       }
  1866. }
  1867. Widget MidasFindWidget(name)
  1868. char *name;
  1869. {
  1870.     Widget w, root;
  1871.     char temp, *p, *path = XtNewString(name);
  1872.  
  1873.     for (p = path+1; *p != '.' && *p != '^' && *p != '\0'; p++);
  1874.  
  1875.     temp = *p;
  1876.     *p = '\0';
  1877.  
  1878.     if (strcmp(path,".") == 0) root = ActiveWidget;
  1879.     else                       root = MidasFindName(path);
  1880.  
  1881.     if (root == 0) MidasError("Could not find widget %s",path);
  1882.  
  1883.     *p = temp;
  1884.     w = MidasTraceWidgetTree(root,p);
  1885.  
  1886.     if (w == 0) MidasError("Could not follow path %s",path);
  1887.  
  1888.     XtFree(path);
  1889.     return w;
  1890. }
  1891. static void MidasDestroy(widget)
  1892. Widget widget;
  1893. {
  1894.     XtDestroyWidget(widget);
  1895. }
  1896. int MidasExit()
  1897. {
  1898.     MidasShell *ms;
  1899.     ListItem *i;
  1900.     int mods = 0;
  1901.     Widget w;
  1902.  
  1903.     for (i = MidasShellList->First; i != 0; i = i->Next)
  1904.       {
  1905.         ms = i->Pointer;
  1906.         mods += ms->Changes; 
  1907.       }
  1908.  
  1909.     if (mods>0)
  1910.       {
  1911.         w = MidasFetch("MidasExitDialog",0);
  1912.         XtManageChild(w);
  1913.         ExitResponse = -1;
  1914.         for (;ExitResponse == -1;) MidasFetchDispatchEvent();
  1915.       }
  1916.     if (ExitResponse == 2 )              /* Cancel */   
  1917.       {
  1918.         XtUnmanageChild(w);
  1919.         return 0;    
  1920.       }
  1921.     if (ExitResponse == 1 )              /* Yes    */
  1922.       for (i = MidasShellList->First; i != 0; i = i->Next)
  1923.         {
  1924.           ms = i->Pointer;
  1925.           if (ms->Changes != 0)
  1926.             {
  1927.               XrmPutFileDatabase(ms->Database, ms->Filename);
  1928.               ms->Changes = 0; 
  1929.             }
  1930.         }
  1931.     return 1;
  1932. }
  1933. static void MidasExitCallback(w,tag,cbDataP)
  1934.       Widget w; 
  1935.       int    *tag; 
  1936.       XmAnyCallbackStruct *cbDataP;
  1937. {
  1938.     ExitResponse = *tag;
  1939. }
  1940. static void MidasQuit()
  1941. {
  1942.     if (CustomExit() && MidasExit()) exit(1);
  1943. }
  1944. void MidasClearWindow(w)
  1945. Widget w;
  1946. {
  1947.     XClearArea(XtDisplay(w),XtWindow(w),0,0,0,0,TRUE);
  1948. }
  1949. void MidasPopup(widget)
  1950. Widget widget;
  1951. {
  1952.     if (XtIsManaged(widget)==0) XtManageChild(widget);
  1953.     else if (XtIsRealized(widget)) 
  1954.       {
  1955.          Widget parent = XtParent(widget);
  1956.          if (XtIsShell(parent)) XRaiseWindow(XtDisplay(parent),XtWindow(parent));
  1957.       }
  1958.  
  1959.     if (XtIsRealized(widget)==0)
  1960.       {
  1961.         MidasShell *ms = MidasGetShell(widget);
  1962.         XtRealizeWidget(ms->Widget);
  1963.       }
  1964. }
  1965. static void MidasPopdown(widget)
  1966. Widget widget;
  1967. {
  1968.     MidasShell *ms = MidasGetShell(widget);
  1969.  
  1970.     if (ms->Widget == widget) widget = MidasTraceWidgetTree(widget,".");
  1971.     if (XtIsManaged(widget)) XtUnmanageChild(widget);
  1972.     if (XtParent(widget) == ms->Widget) XtUnrealizeWidget(ms->Widget); 
  1973.  
  1974. }
  1975. static void MidasToggle(widget)
  1976. Widget widget;
  1977. {
  1978.     if (XtIsManaged(widget)) MidasPopdown(widget);
  1979.     else                     MidasPopup(widget);
  1980. }
  1981. static void MidasCenterHorizontal(w,position)
  1982. Widget w;
  1983. int position;
  1984. {
  1985.     Dimension width;
  1986.     Position  offset;
  1987.     Widget parent = XtParent(w);
  1988.     int n = 0;
  1989.     Arg args[10];
  1990.  
  1991.     XtSetArg(args[n],XmNwidth, &width); n++;
  1992.  
  1993.     if (XmIsForm(parent) == 0)
  1994.       MidasError("Can only center widgets whose parent is FORM");
  1995.  
  1996.     XtGetValues(w,args,n);
  1997.  
  1998.     offset = -((int) width)/2;
  1999.       {
  2000.         int n = 0;
  2001.         Arg args[10];
  2002.         XtSetArg(args[n],XmNleftAttachment, XmATTACH_POSITION); n++;
  2003.         XtSetArg(args[n],XmNleftOffset,     offset);   n++, 
  2004.         XtSetArg(args[n],XmNleftPosition,   position); n++;
  2005.  
  2006.         XtSetValues(w,args,n);
  2007.       }
  2008. }
  2009. static void MidasInvokeApplication(AppName)
  2010. char *AppName;
  2011. {
  2012.     Widget toplevel_widget = MidasCreateShell(AppName);
  2013.     MidasOperand Temp;
  2014.     
  2015.     Temp = MidasGetAppResource(toplevel_widget,"startup");
  2016.     /* printf("\nThe startup string is %s\n",Temp.Value.P); */
  2017.  
  2018.     if (*Temp.Value.P != '\0') MidasQueueCommand(toplevel_widget,Temp.Value.P);
  2019. }                         
  2020. static MidasOperand MidasQueryUser(w)
  2021. Widget w;
  2022. {
  2023.     int flag = 0;
  2024.     Arg arglist[10];  
  2025.  
  2026.     if (!XmIsBulletinBoard(w))
  2027.       MidasError("QUERYUSER requires a widget of subclass BulletinBoard");
  2028.  
  2029.     XtAddCallback(w,XmNunmapCallback,MidasSetFlag,(XtPointer) &flag);
  2030.     XtSetArg(arglist[0],XmNdialogStyle,XmDIALOG_FULL_APPLICATION_MODAL);
  2031.     XtSetValues(w,arglist,1);
  2032.  
  2033.     MidasPopup(w);
  2034.  
  2035.     for (;flag == 0;) 
  2036.       {
  2037.         MidasDispatchQueuedCommands();
  2038.         MidasFetchDispatchEvent(); 
  2039.       }
  2040.  
  2041.     return MidasGetIngot(w,"result");
  2042. }
  2043.  
  2044. /* The names and addresses of Things that Mrm.has to bind.  The names do
  2045.  * not have to be in alphabetical order.  */
  2046.  
  2047. static MrmRegisterArg reglist[] = { 
  2048.     {"midas_command_proc", (caddr_t) midas_command_proc},
  2049.     {"midas_exit", (caddr_t) MidasExitCallback},
  2050.     {"SendMidas", (caddr_t) MidasDispatchCommandCallback}};
  2051.  
  2052. static XtActionsRec actions[] = {
  2053.     {"SendMidas"   , (XtActionProc) MidasSendActionProc},
  2054.     {"MidasSpecial", (XtActionProc) MidasSpecialActionProc}};
  2055.  
  2056. static Boolean MidasConvertStringToCallback(display,args,nargs,from,to,converter_data)
  2057.     Display    *display;
  2058.     XrmValue   *args;
  2059.     Cardinal   *nargs;
  2060.     XrmValue   *from;
  2061.     XrmValue   *to;
  2062.     XtPointer  *converter_data;
  2063. {
  2064.     int size = sizeof(XtPointer);
  2065.     XtPointer new;
  2066.     XtCallbackRec *Callback;
  2067.  
  2068.     if (*from->addr == '\0') Callback = 0;
  2069.     else 
  2070.       { 
  2071.  
  2072.     /* This stuff is currently never freed....need to implement destructor??? */
  2073.  
  2074.         Callback = (XtCallbackRec *) XtMalloc(sizeof(XtCallbackRec)*2);
  2075.         Callback[0].callback = (XtCallbackProc) MidasDispatchCommandCallback;
  2076.         Callback[0].closure  = (XtPointer) XtNewString((char *) from->addr);
  2077.         Callback[1].callback = NULL;
  2078.         Callback[1].closure  = NULL;
  2079.       }
  2080.  
  2081.     new = (XtPointer) &Callback;
  2082.  
  2083.     if (to->addr == 0)
  2084.       {
  2085.          to->addr = new;
  2086.          to->size = size;
  2087.          return TRUE;
  2088.       }
  2089.     else if  (to->size >= size)
  2090.       {
  2091.          memcpy(to->addr,new,size);
  2092.          to->size = size;
  2093.          return TRUE;
  2094.       }
  2095.     else
  2096.       {
  2097.          to->size = size;
  2098.          return FALSE;
  2099.       }
  2100. }
  2101. static Boolean MidasConvertCallbackToString(display,args,nargs,from,to,converter_data)
  2102.     Display    *display;
  2103.     XrmValue   *args;
  2104.     Cardinal   *nargs;
  2105.     XrmValue   *from;
  2106.     XrmValue   *to;
  2107.     XtPointer  *converter_data;
  2108. {
  2109.     XtCallbackRec *Callback = (XtCallbackRec *) from->addr;
  2110.     int size;
  2111.     XtPointer new;
  2112.     static char empty[] = "";
  2113.  
  2114.     if (Callback == 0)
  2115.       {
  2116.         new = empty;
  2117.       }
  2118.     else if (Callback[0].callback == (XtCallbackProc) MidasDispatchCommandCallback)
  2119.       {
  2120.         new = Callback[0].closure;
  2121.       }
  2122.     else 
  2123.       {
  2124.         new = empty;
  2125.       }
  2126.     size = strlen((char *) new) + 1;
  2127.  
  2128.     if (to->addr == 0)
  2129.       {
  2130.          to->addr = new;
  2131.          to->size = size;
  2132.          return TRUE;
  2133.       }
  2134.     else if  (to->size >= size)
  2135.       {
  2136.          memcpy(to->addr,new,size);
  2137.          to->size = size;
  2138.          return TRUE;
  2139.       }
  2140.     else
  2141.       {
  2142.          to->size = size;
  2143.          return FALSE;
  2144.       }
  2145. }
  2146. static Boolean MidasConvertStringTable(display,args,nargs,from,to,converter_data)
  2147.     Display    *display;
  2148.     XrmValue   *args;
  2149.     Cardinal   *nargs;
  2150.     XrmValue   *from;
  2151.     XrmValue   *to;
  2152.     XtPointer  *converter_data;
  2153. {
  2154.     XmString **string = (XmString **) from->addr;
  2155.     char *new;
  2156.     int size;
  2157.  
  2158.     if (*string == 0 || **string == 0)
  2159.       {
  2160.         new = XtNewString("");
  2161.         size = 1;
  2162.       }
  2163.     else
  2164.       {
  2165.         new = MidasStringToChar(**string);
  2166.         size = strlen(new) + 1;
  2167.       } 
  2168.     if (to->addr == 0)
  2169.       {
  2170.          to->addr = new;
  2171.          to->size = size;
  2172.          return TRUE;
  2173.       }
  2174.     else if  (to->size >= size)
  2175.       {
  2176.          strcpy(to->addr,new);
  2177.          to->size = size;
  2178.          XtFree(new);
  2179.          return TRUE;
  2180.       }
  2181.     else
  2182.       {
  2183.          to->size = size;
  2184.          XtFree(new);
  2185.          return FALSE;
  2186.       }
  2187. }
  2188. static Boolean MidasConvertEnum(display,args,nargs,from,to,converter_data)
  2189.     Display    *display;
  2190.     XrmValue   *args;
  2191.     Cardinal   *nargs;
  2192.     XrmValue   *from;
  2193.     XrmValue   *to;
  2194.     XtPointer  *converter_data;
  2195. {
  2196.     char *val = from->addr;
  2197.     char *new;
  2198.     int size;
  2199.     ConvertPair *cp = (ConvertPair *) args->addr;
  2200.  
  2201.     for (; cp->Name != 0; cp++)
  2202.       if (cp->Value == *val) { new = cp->Name; break; }
  2203.  
  2204.     if (cp->Name == 0) return FALSE;
  2205.     size =strlen(new);
  2206.  
  2207.     if (to->addr == 0)
  2208.       {
  2209.          to->addr = new;
  2210.          to->size = size;
  2211.          return TRUE;
  2212.       }
  2213.     else if  (to->size >= size)
  2214.       {
  2215.          strcpy(to->addr,new);
  2216.          to->size = size;
  2217.          return TRUE;
  2218.       }
  2219.     else
  2220.       {
  2221.          to->size = size;
  2222.          return FALSE;
  2223.       }
  2224. }
  2225. static Boolean MidasConvertInteger(display,args,nargs,from,to,converter_data)
  2226.     Display    *display;
  2227.     XrmValue   *args;
  2228.     Cardinal   *nargs;
  2229.     XrmValue   *from;
  2230.     XrmValue   *to;
  2231.     XtPointer  *converter_data;
  2232. {
  2233.     static char buffer[12];
  2234.     int size;
  2235.  
  2236.     if (from->size == sizeof(short int))
  2237.       {
  2238.         int i;
  2239.         short int s; 
  2240.         memcpy(&s,from->addr,sizeof(s));
  2241.         i = s;
  2242.         sprintf(buffer,"%d",i);
  2243.         size = 1 + strlen(buffer);
  2244.       }
  2245.     else
  2246.       {
  2247.         int s;
  2248.         memcpy(&s,from->addr,sizeof(s)); 
  2249.         sprintf(buffer,"%d",s);
  2250.         size = 1 + strlen(buffer);
  2251.       }
  2252.  
  2253.  
  2254.     if (to->addr == 0)
  2255.       {
  2256.          to->addr = buffer;
  2257.          to->size = size;
  2258.          return TRUE;
  2259.       }
  2260.     else if  (to->size >= size)
  2261.       {
  2262.          strcpy(to->addr,buffer);
  2263.          to->size = size;
  2264.          return TRUE;
  2265.       }
  2266.     else
  2267.       {
  2268.          to->size = size;
  2269.          return FALSE;
  2270.       }
  2271. }
  2272. void MidasMainLoop()
  2273. {
  2274.     for (;;)
  2275.       {
  2276.         MidasDispatchQueuedCommands();
  2277.         MidasFetchDispatchEvent();
  2278.       }
  2279. }
  2280. void MidasInvokeAction(w,name)
  2281. Widget w;
  2282. char *name;
  2283. {
  2284.     XtCallActionProc(w,name,NULL,NULL,0);
  2285. }
  2286. void MidasSystem(name)
  2287. char *name;
  2288. {
  2289.     system(name);
  2290. }
  2291. void MidasInvokeCallback(w,name)
  2292. Widget w;
  2293. char *name;
  2294. {
  2295.     XtCallCallbacks(w,name,NULL);
  2296. }
  2297. void MidasFlush(w)
  2298. Widget w;
  2299. {
  2300.     XFlush(XtDisplay(w));
  2301. }
  2302. void MidasUpdate(w)
  2303. Widget w;
  2304. {
  2305.     XmUpdateDisplay(w);
  2306. }
  2307. void MidasInitialize(argc,argv)
  2308. Cardinal argc;
  2309. char *argv[];
  2310. {
  2311.     MrmHierarchy MidasHierarchy;
  2312.     MrmType *dummy_class;
  2313.     Pixmap PixMap;
  2314.     Pixel foreground,background;
  2315.     Widget MidasMenu;
  2316.     char junk[100];
  2317.     MidasOperand Temp;
  2318.     Widget toplevel_widget;
  2319.     int i;
  2320.     
  2321.     for (i=0; i < HASHTABLESIZE; i++) HashTable[i] = NULL;
  2322.  
  2323.     MidasWidgetList = MidasCreateEmptyList("MidasWidgets");
  2324.     MidasFileList   = MidasCreateEmptyList("MidasFiles");
  2325.     MidasShellList  = MidasCreateEmptyList("MidasShells");
  2326.  
  2327.     CommandQueue.Head = 0;
  2328.     CommandQueue.Tail = 0;
  2329.  
  2330.     MrmInitialize();                 /* Initialize MRM before initializing */
  2331.                                      /* the X Toolkit. */
  2332.  
  2333.     /* If we had user-defined widgets, we would register them with Mrm.here. */
  2334.  
  2335.     /* Set up initial command parsing stuff */
  2336.  
  2337.     XtSetTypeConverter("XmStringTable","String",MidasConvertStringTable,
  2338.                        NULL,0,XtCacheNone,NULL);
  2339.     XtSetTypeConverter("ShellVertPos","String",MidasConvertInteger,
  2340.                        NULL,0,XtCacheNone,NULL);
  2341.     XtSetTypeConverter("ShellHorizPos","String",MidasConvertInteger,
  2342.                        NULL,0,XtCacheNone,NULL);
  2343.     XtSetTypeConverter("ShellVertDim","String",MidasConvertInteger,
  2344.                        NULL,0,XtCacheNone,NULL);
  2345.     XtSetTypeConverter("ShellHorizDim","String",MidasConvertInteger,
  2346.                        NULL,0,XtCacheNone,NULL);
  2347.     XtSetTypeConverter("VerticalPosition","String",MidasConvertInteger,
  2348.                        NULL,0,XtCacheNone,NULL);
  2349.     XtSetTypeConverter("HorizontalPosition","String",MidasConvertInteger,
  2350.                        NULL,0,XtCacheNone,NULL);
  2351.     XtSetTypeConverter("VerticalDimension","String",MidasConvertInteger,
  2352.                        NULL,0,XtCacheNone,NULL);
  2353.     XtSetTypeConverter("HorizontalDimension","String",MidasConvertInteger,
  2354.                        NULL,0,XtCacheNone,NULL);
  2355.     XtSetTypeConverter("Dimension","String",MidasConvertInteger,
  2356.                        NULL,0,XtCacheNone,NULL);
  2357.     XtSetTypeConverter("Int","String",MidasConvertInteger,
  2358.                        NULL,0,XtCacheNone,NULL);
  2359.     XtSetTypeConverter("Short","String",MidasConvertInteger,
  2360.                        NULL,0,XtCacheNone,NULL);
  2361.     XtSetTypeConverter("Cardinal","String",MidasConvertInteger,
  2362.                        NULL,0,XtCacheNone,NULL);
  2363.     XtSetTypeConverter("String","Callback",MidasConvertStringToCallback,
  2364.                        NULL,0,XtCacheNone,NULL);
  2365.     XtSetTypeConverter("Callback","String",MidasConvertCallbackToString,
  2366.                        NULL,0,XtCacheNone,NULL);
  2367.     XtSetTypeConverter("Boolean","String",MidasConvertEnum,
  2368.                        ConvertBooleanArg,1,XtCacheNone,NULL);
  2369.     XtSetTypeConverter("Packing","String",MidasConvertEnum,
  2370.                        ConvertPackingArg,1,XtCacheNone,NULL);
  2371.  
  2372.     MidasDeclareInit();
  2373.     MidasConvertInit();
  2374.     MidasDeclareQualifier("PARENT","Widget");
  2375.     MidasDeclareQualifier("UIDFILE","name");
  2376.     MidasDeclareQualifier("ICON","Icon");
  2377.     MidasDeclareQualifier("DIALOG","");
  2378.     MidasDeclareFunction("STRNSPN(name,name)"               ,MidasStrnspn);
  2379.     MidasDeclareFunction("GETWIDGETID(Widget)"              ,MidasGetWidgetId);
  2380.     MidasDeclareFunction("HASCHILDREN(Widget)"              ,MidasHasChildren);
  2381.     MidasDeclareFunction("CHILDRENINTREE(Widget)"           ,MidasChildrenInTree);
  2382.     MidasDeclareFunction("ISMANAGED(Widget)"                ,MidasIsManaged);
  2383.     MidasDeclareFunction("ISREALIZED(Widget)"               ,MidasIsRealized);
  2384.     MidasDeclareFunction("GETVALUE(Widget,name)"            ,MidasGetValue);
  2385.     MidasDeclareFunction("GETAPPRESOURCE(Widget,name)"      ,MidasGetAppResource);
  2386.     MidasDeclareFunction("EVALU8(name)"                     ,MidasEvaluateExpression);
  2387.     MidasDeclareFunction("INT(Float)"                       ,MidasInt);
  2388.     MidasDeclareFunction("FETCH(name,{Widget})"             ,MidasFetchFunction);
  2389.     MidasDeclareFunction("WIDGET(Widget)"                   ,MidasWidgetFunction);
  2390.     MidasDeclareFunction("WIDGETNAME(Widget)"               ,MidasWidgetName);
  2391.     MidasDeclareFunction("WIDGETCLASS(Widget)"              ,MidasWidgetClass);
  2392.     MidasDeclareFunction("PARENT(Widget)"                   ,MidasParent);
  2393.     MidasDeclareFunction("SHELL(Widget)"                    ,MidasShellFunction);
  2394.     MidasDeclareFunction("TYPE(any)"                        ,MidasGetOperandType);
  2395.     MidasDeclareFunction("GETCOMMAND()"                     ,MidasGetCommand);
  2396.     MidasDeclareFunction("GETCLICKCOUNT()"                  ,MidasGetClickCount);
  2397.     MidasDeclareFunction("HYPERGETTEXT()"                   ,MidasHyperGetText);
  2398.     MidasDeclareFunction("HYPERGETHIDDEN()"                 ,MidasHyperGetHidden);
  2399.     MidasDeclareFunction("QUERYUSER(Widget)"                ,MidasQueryUser);
  2400.     MidasDeclareFunction("HYPERGREP(Widget,name)"           ,MidasHyperGrep);
  2401.     MidasDeclareFunction("TREETOWIDGET(Widget)"             ,MidasTreeToWidget);
  2402.     MidasDeclareVerb("MIDAS *name..."                       ,MidasIgnore);
  2403.     MidasDeclareVerb("POPUP        Widget"                  ,MidasPopup);
  2404.     MidasDeclareVerb("POPDOWN      Widget"                  ,MidasPopdown);
  2405.     MidasDeclareVerb("TOGGLE       Widget"                  ,MidasToggle);
  2406.     MidasDeclareVerb("FETCH        name {Widget}"           ,MidasFetch);
  2407.     MidasDeclareVerb("DESTROY      Widget"                  ,MidasDestroy);
  2408.     MidasDeclareVerb("OPEN UID     name {Widget}"           ,MidasOpenUidFile);
  2409.     MidasDeclareVerb("CREATE SHELL name"                    ,MidasCreateShell);
  2410.     MidasDeclareVerb("CREATE WIDGET TREE Widget"            ,MidasCreateWidgetTree);
  2411.     MidasDeclareVerb("CREATE DIALOG name"                   ,MidasCreateDialog);
  2412.     MidasDeclareVerb("CREATE WIDGET Widget Class name"      ,MidasCreateWidget);
  2413.     MidasDeclareVerb("QUIT"                                 ,MidasQuit);
  2414.     MidasDeclareVerb("REGISTER NAME name Widget"            ,MidasRegisterName);
  2415.     MidasDeclareVerb("TOGGLE CHILDREN Widget"               ,MidasToggleChildrenTree);
  2416.     MidasDeclareVerb("GET CALLBACKS list Widget"            ,MidasGetCallbacks);
  2417.     MidasDeclareVerb("GET RESOURCES list Widget"            ,MidasGetResources);
  2418.     MidasDeclareVerb("SET VALUE Widget name any..."         ,MidasSetValue);    
  2419.     MidasDeclareVerb("SET SENSITIVE Widget Boolean"         ,MidasSetSensitive);    
  2420.     MidasDeclareVerb("SAVE GEOMETRY Widget"                 ,MidasSaveGeometry);
  2421.     MidasDeclareVerb("STORE RESOURCE Widget name"           ,MidasStoreResource);
  2422.     MidasDeclareVerb("STORE APP RESOURCE Widget name name"  ,MidasStoreAppResource);
  2423.     MidasDeclareVerb("SAVE STORED RESOURCES Widget"         ,MidasSaveStoredResources);
  2424.     MidasDeclareVerb("CENTER HORIZONTAL Widget Int"         ,MidasCenterHorizontal);
  2425.     MidasDeclareVerb("CLEAR WINDOW Widget",                  MidasClearWindow);
  2426.     MidasDeclareVerb("CURRENT WIDGET IN TREE Widget"        ,MidasCurrentWidgetInTree);
  2427.     MidasDeclareVerb("IF Boolean *name...",                  MidasIf);
  2428.     MidasDeclareVerb("ELSE IF Boolean *name...",             MidasElseIf);
  2429.     MidasDeclareVerb("ELSE *name...",                        MidasElse);
  2430.     MidasDeclareVerb("INVOKE ACTION Widget name",            MidasInvokeAction);
  2431.     MidasDeclareVerb("INVOKE CALLBACK Widget name",          MidasInvokeCallback);
  2432.     MidasDeclareVerb("LOAD IMAGE name",                      MidasLoadImage);
  2433.     MidasDeclareVerb("FLUSH Widget",                         MidasFlush);
  2434.     MidasDeclareVerb("UPDATE Widget",                        MidasUpdate);
  2435.     MidasDeclareVerb("FORCE DIALOG Widget",                  MidasForceDialog); 
  2436.     MidasDeclareVerb("SYSTEM name...",                       MidasSystem);
  2437.     MidasDeclareVerb("INVOKE APPLICATION name",              MidasInvokeApplication);
  2438.     MidasDeclareVerb("SET CURSOR Widget Cursor",             MidasSetCursor);
  2439.     MidasDeclareVerb("ERROR name...",                        MidasError);
  2440.     MidasDeclareVerb("BEEP {Int} {Widget}",                  MidasBeep);
  2441.     MidasDeclareVerb("HYPER LOAD FILE Widget name",          SGMLHyperLoadFile);
  2442.     MidasDeclareVerb("LIST SELECT ITEM Widget XmString {Boolean}",XmListSelectItem);
  2443.     MidasDeclareVerb("HELP ON CONTEXT Widget",               MidasHelpOnContext);
  2444.         
  2445.     MidasUtilInit();
  2446.     MidasListInit();
  2447.     MidasInitializeIngots();
  2448.  
  2449.     /* Initialize the X Toolkit. We get back a top level shell widget. */
  2450.  
  2451.     XtToolkitInitialize();
  2452.  
  2453.     app_context = XtCreateApplicationContext();
  2454.  
  2455.     /* declare SendMidas action routine */
  2456.  
  2457.     XtAppAddActions(app_context,actions,XtNumber(actions));
  2458.  
  2459.     /* Parse the special midas translations */
  2460.  
  2461.     MidasTranslations = XtParseTranslationTable("Ctrl <Btn1Down> : MidasSpecial(\"Set Ingot WidgetList currentWidget Widget(.):dialog;Popup MidasInfo:parent=WidgetList;Register Name WidgetName(.) .\")");
  2462.                                                                   
  2463.     toplevel_widget = MidasCreateShellArg("Midas",argv,&argc);
  2464.     
  2465.     /* Open the UID files (the output of the UIL compiler) in the hierarchy*/
  2466.  
  2467.     MidasHierarchy = MidasOpenUidFile("midas.uid",toplevel_widget);
  2468.  
  2469.     /* Register the items MRM needs to bind for us. */
  2470.  
  2471.     MrmRegisterNames(reglist,XtNumber(reglist));
  2472.  
  2473.     /* Go get the midas pixmap */
  2474.  
  2475.     PixMap = MidasFetchIcon("MidasIcon");
  2476.  
  2477.     { int n = 0;
  2478.       Arg args[10];
  2479.       XtSetArg(args[n],XmNiconPixmap, PixMap); n++;
  2480.       XtSetValues(toplevel_widget, args, n);
  2481.     }
  2482.  
  2483.     /* Initialize Customization stuff */
  2484.  
  2485.     CustomInit();
  2486.  
  2487.     /* Invoke the users profile */
  2488.  
  2489.     {
  2490.       char *AppName, *AppClass;
  2491.       XtGetApplicationNameAndClass(XtDisplay(toplevel_widget),&AppName,&AppClass); 
  2492.       /* printf("Application name %s",AppName); */
  2493.  
  2494.       if (strcmp(AppName,"midas") && strcmp(AppName,"MIDAS") && strcmp(AppName,"Midas"))
  2495.         {
  2496.           toplevel_widget = MidasCreateShell(AppName);
  2497.         }
  2498.     }
  2499.  
  2500.     Temp = MidasGetAppResource(toplevel_widget,"startup");
  2501.     /* printf("\nThe startup string is %s\n",Temp.Value.P); */
  2502.  
  2503.     if (*Temp.Value.P != '\0') MidasQueueCommand(toplevel_widget,Temp.Value.P);
  2504.     else                       MidasQueueCommand(toplevel_widget,"Midas Popup Midas_Main");
  2505.  
  2506. };
  2507.